package com.xqboss.apps.service.consumer;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.domain.consumer.*;
import com.xqboss.apps.dto.consumer.ConsumerApplyDto;
import com.xqboss.apps.enums.consumer.*;
import com.xqboss.apps.mapper.consumer.ConsumerTeamApplyMapper;
import com.xqboss.apps.mapper.consumer.ConsumerTeamMapper;
import com.xqboss.apps.vo.consumer.ConsumerTeamApplyVo;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.LocalDateUtils;
import com.xqboss.common.utils.SecurityUtils;
import com.xqboss.common.utils.SocketUtil;
import com.xqboss.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 队伍申请Service业务层处理
 *
 * @author xqboss
 * @date 2023-08-17
 */
@Service
@Slf4j
public class ConsumerTeamApplyService extends ServiceImpl<ConsumerTeamApplyMapper, ConsumerTeamApply> {

    @Resource
    private ConsumerTeamApplyMapper consumerTeamApplyMapper;
    @Autowired
    @Lazy
    private ConsumerTeamApplyService consumerTeamApplyService;
    @Resource
    private ConsumerTeamMemberService consumerTeamMemberService;
    @Resource
    private ConsumerTeamMapper consumerTeamMapper;
    @Resource
    private ConsumerTeamService consumerTeamService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Autowired
    private ConsumerInteractMsgService consumerInteractMsgService;
    @Resource
    private ConsumerTeamMsgRecordService consumerTeamMsgRecordService;


    @Transactional(rollbackFor = Exception.class)
    public R updateConsumerApply(ConsumerApplyDto dto) {
        if (ObjUtil.isNull(dto.getId()) || ObjUtil.isNull(dto.getHandlerUserId())) {
            return R.fail("参数错误");
        }
        ConsumerTeamApply res = consumerTeamApplyMapper.selectById(dto.getId());
        if (ObjUtil.isNull(res)) {
            return R.fail("申请记录不存在");
        }
        ConsumerTeamApply apply = new ConsumerTeamApply();
        apply.setId(dto.getId());
        apply.setStatus(dto.getStatus().getValue());
        consumerTeamApplyMapper.updateById(apply);

        ConsumerTeam team = consumerTeamMapper.selectById(res.getTeamId());
        if (ObjUtil.isNull(team)) {
            return R.fail("队伍已经解散啦~");
        }
        if (Objects.requireNonNull(dto.getStatus()) == ConsumerApplyStatusEnum.AGREED) {
            if (team.getMemberCount() >= team.getMaxNumber()) {
                throw new ServiceException("队伍满员啦~");
            }

            LambdaQueryWrapper<ConsumerTeamMember> wq2 = new LambdaQueryWrapper<>();
//            wq2.eq(ConsumerTeamMember::getTeamId, team.getId());
            wq2.eq(ConsumerTeamMember::getUserId, dto.getHandlerUserId());
            ConsumerTeamMember handlerMember = consumerTeamMemberService.getOne(wq2);
            if (ObjUtil.isNotNull(handlerMember)) {
                throw new ServiceException("已加入其他队伍了哦~");
            }

            if (res.getType() == 1) {
                LambdaQueryWrapper<ConsumerTeamMember> wq = new LambdaQueryWrapper<>();
                wq.eq(ConsumerTeamMember::getTeamId, team.getId());
                wq.eq(ConsumerTeamMember::getUserId, dto.getUserId());
                ConsumerTeamMember currentMember = consumerTeamMemberService.getOne(wq);
                if (ObjUtil.isNull(currentMember)
                        || ObjUtil.notEqual(currentMember.getRole(), ConsumerTeamRoleEnum.ADMINISTRATOR.getValue())) {
                    throw new ServiceException("不是队伍管理员~");
                }

                ConsumerTeamMember teamMember = new ConsumerTeamMember();
                teamMember.setTeamId(res.getTeamId());
                teamMember.setRole(ConsumerTeamRoleEnum.ORDINARY_MEMBER.getValue());
                teamMember.setJoinTime(LocalDateUtils.getCurrentLocalDateTime());
                //被处理的人
                teamMember.setUserId(dto.getHandlerUserId());
                //队伍消息记录已读位置id
                teamMember.setTeamMsgId(consumerTeamMsgRecordService.findLastId());
                //邀请家庭成员
                if (res.getMemberType() != null) {
                    teamMember.setType(res.getMemberType());
                    teamMember.setParentId(res.getMemberType() == ConsumerTeamMemberTypeEnum.TYPE_MAIN ? 0 : res.getInviteId());
                }
                boolean b = consumerTeamMemberService.save(teamMember);
                int i = consumerTeamMapper.addMemberCount(res.getTeamId(), 1);

                //添加队伍消息记录
                ConsumerTeamMsgRecord msgRecord = new ConsumerTeamMsgRecord();
                msgRecord.setType(ConsumerMsgRecordEnum.MEMBER_ALTER.getValue());
                msgRecord.setTeamId(team.getId());
                msgRecord.setFromUserId(dto.getHandlerUserId());
                msgRecord.setToUserId(dto.getHandlerUserId());
                msgRecord.setContent(sysUserMapper.getNameById(dto.getHandlerUserId()) + "加入~");
                msgRecord.setSourceId(Long.valueOf(teamMember.getId()));
                boolean save = consumerTeamMsgRecordService.save(msgRecord);
                if (!save || !b || i != 1) {
                    throw new ServiceException("处理失败");
                }

            } else if (res.getType() == 2) {
                ConsumerTeamMember teamMember2 = new ConsumerTeamMember();
                teamMember2.setTeamId(res.getTeamId());
                teamMember2.setRole(ConsumerTeamRoleEnum.ORDINARY_MEMBER.getValue());
                teamMember2.setJoinTime(LocalDateUtils.getCurrentLocalDateTime());
                //被处理的人
                teamMember2.setUserId(dto.getUserId());
                //队伍消息记录已读位置id
                teamMember2.setTeamMsgId(consumerTeamMsgRecordService.findLastId());
                teamMember2.setInviteUserId(res.getUserId());
                //邀请家庭成员
                if (res.getMemberType() != null) {
                    teamMember2.setType(res.getMemberType());
                    teamMember2.setParentId(res.getMemberType() == ConsumerTeamMemberTypeEnum.TYPE_MAIN ? 0 : res.getInviteId());
                }
                boolean x = consumerTeamMemberService.save(teamMember2);
                int y = consumerTeamMapper.addMemberCount(res.getTeamId(), 1);

                //添加队伍消息记录
                ConsumerTeamMsgRecord msg = new ConsumerTeamMsgRecord();
                msg.setType(ConsumerMsgRecordEnum.MEMBER_ALTER.getValue());
                msg.setTeamId(team.getId());
                msg.setFromUserId(dto.getUserId());
                msg.setToUserId(dto.getUserId());
                msg.setContent(sysUserMapper.getNameById(res.getUserId()) + "邀请" + sysUserMapper.getNameById(dto.getUserId()) + "加入~");
                msg.setSourceId(Long.valueOf(teamMember2.getId()));
                boolean s = consumerTeamMsgRecordService.save(msg);
                if (!s || !x || y != 1) {
                    throw new ServiceException("处理失败");
                }
            } else {
                throw new ServiceException("错误的类型");
            }
        }
        if (res.getType() == 2) { //管理员邀请单独处理
            dto.setHandlerUserId(res.getUserId());
        }
        //站内信V23.9.7 编辑队伍申请记录
        ConsumerInteractMsg msg = new ConsumerInteractMsg();
        msg.setUserId(dto.getHandlerUserId());
        if (Objects.requireNonNull(dto.getStatus()) == ConsumerApplyStatusEnum.AGREED) {
            msg.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_CONSENT.getMsg());
            msg.setType(InteractMsgEnum.TEAM_CONSENT);
            //同意入队
            SocketUtil.sendOneMessage(String.valueOf(dto.getHandlerUserId()), SecurityUtils.getNickName() + InteractMsgEnum.TEAM_CONSENT.getMsg(),
                    InteractMsgEnum.TEAM_CONSENT.getValue(), Long.valueOf(apply.getId()));
            //同意了提醒自己
            SocketUtil.sendOneMessage(String.valueOf(dto.getUserId()), sysUserMapper.getNameById(dto.getHandlerUserId()) + "已加入队伍",
                    InteractMsgEnum.TEAM_CONSENT.getValue(), Long.valueOf(apply.getId()));
            //刷新队伍打卡次数
            consumerTeamService.refreshPunchGain(Long.valueOf(res.getTeamId()));
            //其它待审核的申请 和 邀请我的记录 记为已超时
            consumerTeamApplyService.actionTimeOutWhenJoinTeam(dto.getHandlerUserId());
            //队伍满员后，待审核的 申请该队伍的用户 和 该队伍邀请过的用户 记为已超时
            if (team.getMemberCount()+1 >= team.getMaxNumber()) {
                consumerTeamApplyService.actionTimeOutWhenTeamFullOrDisBand(Integer.toUnsignedLong(dto.getTeamId()));
            }
        } else if (Objects.requireNonNull(dto.getStatus()) == ConsumerApplyStatusEnum.REJECTED) {
            msg.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_REFUSE.getMsg());
            msg.setType(InteractMsgEnum.TEAM_REFUSE);
            //拒绝入队
            SocketUtil.sendOneMessage(String.valueOf(dto.getHandlerUserId()), SecurityUtils.getNickName() + InteractMsgEnum.TEAM_REFUSE.getMsg(),
                    InteractMsgEnum.TEAM_REFUSE.getValue(), Long.valueOf(apply.getId()));
        }
        msg.setSourceId(Long.valueOf(apply.getId()));
        consumerInteractMsgService.save(msg);
        return R.ok();
    }

    public List<ConsumerTeamApplyVo> selectByDto(ConsumerTeamApply dto) {
        return consumerTeamApplyMapper.selectConsumerTeamApplyList(dto);
    }

    public List<ConsumerTeamApplyVo> getMyApply(ConsumerTeamApply dto) {
        return consumerTeamApplyMapper.getMyApply(dto);
    }

    /**
     * 加入队伍成功，该用户的其它队伍申请 和 邀请过该用户的队伍 置为已超时
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public void actionTimeOutWhenJoinTeam(Long userId){
        Assert.notNull(userId, ()->new ServiceException("用户id不能为空"));
        //1 该用户的其它队伍申请,状态为待处理的置为已超时
        boolean a = this.lambdaUpdate()
                .set(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.TIMED_OUT)
                .eq(ConsumerTeamApply::getUserId, userId)
                .eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue())
                .eq(ConsumerTeamApply::getType, ConsumerApplyTypeEnum.USER_APPLY.getValue())
                .update();
        //2 邀请过该用户的队伍，状态为待处理的置为已超时
        boolean b = this.lambdaUpdate()
                .set(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.TIMED_OUT)
                .eq(ConsumerTeamApply::getHandlerUserId, userId)
                .eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue())
                .nested(wq -> wq.eq(ConsumerTeamApply::getType, ConsumerApplyTypeEnum.USER_APPLY.getValue())
                             .or().eq(ConsumerTeamApply::getType, ConsumerApplyTypeEnum.ADMINISTRATOR_INVITATION.getValue()))
                .update();
        //这儿就不判断是否更新成功了，有可能就不存在带通过的
//        if (!a || !b){  throw new ServiceException("已超时状态更新失败~"); }
    }

    /**
     * 队伍满员或解散，申请过该队伍的和该队伍邀请过的置为已超时
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public void actionTimeOutWhenTeamFullOrDisBand(Long teamId){
        Assert.notNull(teamId, ()->new ServiceException("队伍id不能为空"));
        //申请过该队伍的,该队伍邀请过的，状态为待处理的置为已超时
        boolean a = this.lambdaUpdate()
                .set(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.TIMED_OUT)
                .eq(ConsumerTeamApply::getTeamId, teamId)
                .eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue())
                .update();
        //这儿就不判断是否更新成功了，有可能就不存在带通过的
//        if (!a){  throw new ServiceException("已超时状态更新失败~"); }
    }
}
